package com.scut.filedownloader.core.recorder;

import android.content.SharedPreferences;

import androidx.annotation.MainThread;

import com.scut.filedownloader.FileDownloader;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 该类对应操作 持久化的"Map<String,Integer>"类，用来记录下载条目，Integer标记该条目id,Key值String对应pathname
 * 该类用于查找对应的下载项是否已经存在。
 * 键值对: Key 为任务id,
 */
public class DownloadEntryRecorder {

    private SharedPreferences sharedPreferences;
    static private String downloadEntryPrefix= FileDownloader.getInstance().downloadRecordName;
    static private String entryIdAllocKey="id_next";

    public DownloadEntryRecorder(SharedPreferences sharedPreferences){
        this.sharedPreferences=sharedPreferences;
        correctNextIdValueIfNeeded();
    }

    public int getEntriesCount(){
        return sharedPreferences.getAll().size();
    }


    public void addEntry(String pathname){
        SharedPreferences.Editor editor=sharedPreferences.edit();
        if(checkEntryName(pathname)) {
            editor.putInt(pathname, getEntriesCount());
            final int id_next=sharedPreferences.getInt(entryIdAllocKey,0);
            editor.putInt(DownloadEntryRecorder.entryIdAllocKey,id_next+1); //increase id
            editor.apply();
        }
    }



    @Deprecated
    public void addEntry(String pathname,int id){
        SharedPreferences.Editor editor=sharedPreferences.edit();
        editor.putInt(pathname,id);
        editor.apply();
    }

    /**
     * 转换value类型
     * @return
     */
    public Map<String,Integer> getAllEntries(){
        Map<String,?> map=sharedPreferences.getAll();
        Set<String> keySet=map.keySet();
        Map<String,Integer> resultSet=new HashMap<>();
        for(String key: keySet){
            Object value=map.get(key);
            resultSet.put(key, (Integer) value);
        }
        resultSet.remove(entryIdAllocKey);
        return resultSet;
    }

    /**
     * 获取pathname所指任务id
     * @param pathname
     * @return -1 为不存在该条目
     */
    public int getEntryId(String pathname){
        if(sharedPreferences.contains(pathname)){
            return sharedPreferences.getInt(pathname,-1);
        }
        else{
            return -1;
        }
    }


    /**
     * 清空所有条目记录
     */
    public void clearAll(){
        sharedPreferences.edit().clear().apply();
    }

    /**
     * 在本记录条目里删除该记录，同时在永久存储上删除对应条目
     * @param pathname
     */
    @MainThread
    public void deleteRecordEntry(String pathname){
        if(sharedPreferences.contains(pathname)){
            final int id=sharedPreferences.getInt(pathname,-1);
            if(id!=-1){
                 sharedPreferences.edit().remove(pathname).commit();
                 FileDownloader.getInstance().deleteSharedPreferences(downloadEntryPrefix+id);
            }
        }
    }

    /**
     * 通过full_pathname获取到记录器，如果条目不存在，则会自动创建
     * @param full_pathname
     * @return null 表示遭遇异常且无法修正
     */
    public DownloadRecorder getDownloadRecorder(String full_pathname){
        DownloadRecorder recorder;
        int id=getEntryId(full_pathname);
        if(id==-1){
            addEntry(full_pathname);
            id=getEntryId(full_pathname);
            //check again
            if(id==-1){
                return null;
            }
        }
        recorder= FileDownloader.getInstance().getRecorderFactory().getDownloadRecorder(id);
        return recorder;
    }

    public DownloadRecorder getDownloadRecorder(int id){
        return FileDownloader.getInstance().getRecorderFactory().getDownloadRecorder(id);
    }

    private boolean checkEntryName(String entryName){
        return !entryName.contentEquals(DownloadEntryRecorder.entryIdAllocKey);
    }

    @Override
    protected void finalize() {
        sharedPreferences.edit().apply();
    }

    private void correctNextIdValueIfNeeded(){
        int next_id=sharedPreferences.getInt(entryIdAllocKey,0);
        boolean contain=true;
        Map<String, ?> map = sharedPreferences.getAll();
        while(contain) {
            contain=map.containsValue(next_id);
            next_id+=2; //jump
        }
    }
}
